package com.learn;

import java.util.HashMap;

/**
 * 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ，验证已经填入的数字是否有效即可。
 * <p>
 * 数字 1-9 在每一行只能出现一次。
 * 数字 1-9 在每一列只能出现一次。
 * 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。（请参考示例图）
 * <p>
 * <p>
 * 注意：
 * <p>
 * 一个有效的数独（部分已被填充）不一定是可解的。
 * 只需要根据以上规则，验证已经填入的数字是否有效即可。
 * 空白格用 '.' 表示。
 * <p>
 * [1,2,3,4,5,6,7,8,9]----1
 * [1,2,3,4,5,6,7,8,9]----2
 * [1,2,3,4,5,6,7,8,9]----3
 * [1,2,3,4,5,6,7,8,9]----4
 * [1,2,3,4,5,6,7,8,9]----5
 * [1,2,3,4,5,6,7,8,9]----6
 * [1,2,3,4,5,6,7,8,9]----7
 * [1,2,3,4,5,6,7,8,9]----8
 * [1,2,3,4,5,6,7,8,9]----9
 * 第i行，第j列
 * i/3行，j/3列范围内不重复
 */

public class num_36 {
    public static boolean isValidSudoku(char[][] board) {
        int innerLen = board[0].length;
        int outsideLen = board.length;
        boolean flag=true;
        if (innerLen != 9 || outsideLen != 9) {
            return false;
        }
        //现在有个问题：如何将矩阵里的'.'去除掉，将剩余的留下比较？
        for (int i = 0; i < outsideLen; i++) {
            char[] chars = board[i];
            char[] innerChars = new char[innerLen];
            char[] squareChars = new char[innerLen];
            for (int j = 0; j < innerLen; j++) {
                innerChars[j] = board[j][i];
                if (i % 3 == 0 && j % 3 == 0) {
                    squareChars=new char[]{
                            board[i][j],board[i][j+1],board[i][j+2],
                            board[i+1][j],board[i+1][j+1],board[i+1][j+2],
                            board[i+2][j],board[i+2][j+1],board[i+2][j+2],
                    };
                    flag =isComplied(squareChars)&&flag;
                }
                if (!flag) {
                    return flag;
                }
            }
            //剩下一种可以用i/3和j/3解决
            flag=isComplied(chars)&&isComplied(innerChars);
            if (!flag) {
                return flag;
            }
        }
        return flag;

    }
    public static boolean isComplied(char[] chars){
        HashMap<Character, Integer> CIMap = new HashMap<>();
        for (char aChar : chars) {
            if (aChar != '.') {
                CIMap.put(aChar, CIMap.getOrDefault(aChar, 0) + 1);
            }
        }
        //如果大于2呢？
        for (Integer value : CIMap.values()) {
            if (value > 1) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        char[][] board = {
                {'5','3','.','.','7','.','.','.','.'}
                ,{'6','.','.','1','9','5','.','.','.'}
                ,{'.','9','8','.','.','.','.','6','.'}
                ,{'8','.','.','.','6','.','.','.','3'}
                ,{'4','.','.','8','.','3','.','.','1'}
                ,{'7','.','.','.','2','.','.','.','6'}
                ,{'.','6','.','.','.','.','2','8','.'}
                ,{'.','.','.','4','1','9','.','.','5'}
                ,{'.','.','.','.','8','.','.','7','9'}};
        
        char[][] board1 = {
                {'8','3','.','.','7','.','.','.','.'},
                {'6','.','.','1','9','5','.','.','.'},
                {'.','9','8','.','.','.','.','6','.'},
                {'8','.','.','.','6','.','.','.','3'},
                {'4','.','.','8','.','3','.','.','1'},
                {'7','.','.','.','2','.','.','.','6'},
                {'.','6','.','.','.','.','2','8','.'},
                {'.','.','.','4','1','9','.','.','5'},
                {'.','.','.','.','8','.','.','7','9'}};
        System.out.println(isValidSudoku(board1));
        System.out.println(isValidSudoku(board));
    }

}
